package com.autonavi.yunda.yunji.core.engine.scriptresolver;


/**
 * @author cizhong.wcs
 * @date 2022/6/20 11:02
 */
public class GeneratorWriter<W extends GeneratorWriter<W>> {
    protected final StringBuilder sb;
    protected int indentTabs;
    protected String tabString = "  ";
    protected String newlineString = "\n";
    protected boolean newline = true;

    protected GeneratorWriter() {
        this.sb = new StringBuilder();
    }

    @SuppressWarnings("unchecked")
    public W print(char value) {
        print("" + value);
        return (W) this;
    }

    @SuppressWarnings("unchecked")
    public W print(int value) {
        print("" + value);
        return (W) this;
    }

    @SuppressWarnings("unchecked")
    public W print(String string) {
        print(string, new Object[0]);
        return (W) this;
    }

    @SuppressWarnings("unchecked")
    public W print(String string, Object... args) {
        if (newline && indentTabs > 0) {
            for (int i = 0; i < indentTabs; i++) {
                sb.append(tabString);
            }
            newline = false;
            indentTabs = 0;
        }
        if (args.length > 0) {
            sb.append(String.format(string, args));
        } else {
            sb.append(string);
        }
        return (W) this;
    }

    @SuppressWarnings("unchecked")
    public W println() {

        // Don't add empty lines at the beginning of files
        if (sb.length() > 0) {
            sb.append(newlineString);
            newline = true;
        }

        return (W) this;
    }

    @SuppressWarnings("unchecked")
    public W println(int value) {
        print(value);
        println();

        return (W) this;
    }

    @SuppressWarnings("unchecked")
    public W println(String string) {
        print(string);
        println();

        return (W) this;
    }

    @SuppressWarnings("unchecked")
    public W println(String string, Object... args) {
        print(string, args);
        println();
        return (W) this;
    }

    @SuppressWarnings("unchecked")
    public W tab(int tabs) {
        this.indentTabs = tabs;
        return (W) this;
    }

    @Override
    public String toString() {
        return sb.toString();
    }
}
